<!DOCTYPE html>
<html lang='en'>

<head>
  <meta charset='UTF-8'>
  <meta http-equiv='X-UA-Compatible' content='IE=edge'>
  <meta name='viewport' content='width=device-width, initial-scale=1.0'>
  <link rel='stylesheet' href='./layui-v2.9.10/layui/css/layui.css' media='all'>
  <link rel='stylesheet' href='./css/books.css' media='all'>
  <link rel="shortcut icon" type="image/x-icon" href="./images/favicon.png" media="screen">
  <title>在线epub阅读 - 书架</title>
</head>

<body>
  <!-- 让 IE8/9 支持媒体查询，从而兼容栅格 -->
  <!--[if lt IE 9]>
    <script src="https://cdn.staticfile.org/html5shiv/r29/html5.min.js"></script>
    <script src="https://cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
  <![endif]-->

  <div class="layui-container">
    <div class="layui-row layui-col-space32"
      style="display: flex; justify-content: center; flex-direction: row; flex-wrap: wrap;width: 100%;">
      <div class="layui-col-xs12 layui-col-ms12 layui-col-md11">
        <h3
          style="display: flex; justify-content: center; font-size: 16px; color: #b9b9b9; height: 52px; align-items: center;">
          在线epub阅读，支持本地上传、远程链接</h3>
      </div>
      <div class="layui-col-xs12 layui-col-ms12 layui-col-md8">

        <div class="layui-row layui-col-space5">
          <div class="layui-col-md4">
            <div class="updateFile">上传本地epub文件
              <input type="file" multiple class="file" id="inputFile">
            </div>
          </div>
          <div class="layui-col-md8 updateUrl">
            <input type="text" id="updateUrl_input" placeholder="要求链接地址目标是epub文件" class="layui-input updateUrl_input">
            <button class="layui-btn updateUrl_button" lay-on="getUrlBook">立即提交</button>
          </div>
        </div>

      </div>
      <div class="layui-col-xs12 layui-col-ms12 layui-col-md8">

        <div class="layui-row layui-col-space26" id="books">

          <!-- <div class="layui-col-xs6 layui-col-ms12 layui-col-md3 ">
            <div class="delete">
              <i class="layui-icon layui-icon-clear" style="font-size: 30px; color: #ff8080;"></i>
            </div>
            <a href="http://" target="_blank" rel="noopener noreferrer">
              <div class="bookImg">
                <img src="http://wenjian.wuweijun.fun:999/files//0531_1026_微信截图_20240531130838.png" alt="" srcset="">
              </div>
              <div class="bookTitle">自控力</div>
              <div class="read">
                <div class="bookType">远程-</div>
                <div class="bookCreator">凯利•麦格尼格尔利•麦格尼格尔利•麦格尼格尔</div>
                <div class="bookRead">30%</div>
              </div>
            </a>
          </div> -->

        </div>

      </div>
      <div class="layui-col-xs12 layui-col-ms12 layui-col-md8" style="background-color: #d1d1d1;">
        <span>友情链接：</span>
        <a href="http://wenjian.wuweijun.fun/" target="_blank" rel="noopener noreferrer"
          style="color: #16baaa;">临时文件传输</a>
      </div>
    </div>
  </div>
  <div id="view"> </div>
  <div id="function">
  </div>

  <script src="./js/jszip.min.js"></script>
  <!-- 不用使用其他的epub.js,因为有修改过源码：在源码中搜索：源码有改动 -->
  <script src="./js/epub.js"></script>
  <!-- idb-keyval使用方法 https://dgithub.xyz/jakearchibald/idb-keyval#readme -->
  <script src="./js/idb-keyval.js"></script>
  <script src="./js/tools.js"></script>
  <script src='./layui-v2.9.10/layui/layui.js'></script>
  <script>
    // if (isMobileDevice()) location.href = 'MobileDevice.html';
    let { set, setMany, get, getMany, update, del, delMany, clear, entries, keys, values, } = idbKeyval;

    // 操作upub库的方法
    let epubFunc = {
      InitBook: function (urlOrArrayBuffer, id) {
        /* 添加图书，参数是url或者本地上传的文件，id为一个新的div的id */
        let book = ePub();
        let rendition;
        let displayed;
        book.open(urlOrArrayBuffer).then(null, e => {
          alert('加载图书异常，请确认是否为epub文件，错误信息如下：\n\n' + e.message);
          layer.close(loadIndex);
        });
        return book;
      },
      getInfo(book) {
        /* 图书基本信息：书名+作者+图片 */
        let info = { title: '', creator: '', cover: '', blob: undefined, identifier: parseInt(Math.random() * 1000000000000) };
        function f(resolve, reject) {
          book.loaded.metadata.then(function (meta) {
            info.title = meta.title.trim(); info.creator = meta.creator.trim(); info.identifier = meta.identifier;
            if (book.archive) {
              try {
                book.archive.createUrl(book.cover).then(function (url_) {
                  info.cover = url_;
                  info.blob = book.archive.blob[book.cover];
                  resolve(info);
                }, error => {
                  alert('发送错误:' + error.message);
                  setTimeout(() => { f(resolve, reject); alert('error') }, 150);
                })
              } catch (error) {
                alert(`发生如下错误，或许你应该换个epub文件，这个文件加载异常：\n\n ${error.message}`);
                layer.close(loadIndex);
              }
            } else {
              info.cover = book.cover; resolve(info);
            }
          });
        }
        return new Promise((resolve, reject) => { f(resolve, reject) })
      },
      createDiv: function () {
        var newDiv = document.createElement("div");
        let id = Math.floor(Math.random() * 16777215).toString(16);
        newDiv.setAttribute("id", id);
        newDiv.classList.add('none');
        document.body.appendChild(newDiv);
        return id;
      },
      blobToBase64: function (blob, fn = Function) {
        /* 实际的 Blob 对象  转换成base64。另一种方法：将 Blob URL 中的图片加载到 Canvas 并转换为 Base64 编码的字符串 */
        // 使用 FileReader API 读取 Blob 并转换为 Base64  
        var reader = new FileReader();
        reader.readAsDataURL(blob); // 读取为 Data URL，它实际上是 Base64 编码的字符串，前缀为 "data:[<mediatype>][;base64],<data>"  
        reader.onloadend = function () {
          var base64data = reader.result; // 当读取完成后，result 属性将包含 Data URL  
          // 如果你只需要纯 Base64 编码的字符串（不带 "data:" 前缀和媒体类型），可以使用以下代码：  
          // console.log(base64data); // 输出纯 Base64 编码的字符串  
          fn && fn(base64data)
        };
      }
    }

    let updateType = '本地';
    // 上传文件
    document.getElementById('inputFile').addEventListener('change', function (event) {
      var files = event.target.files;
      for (let i = 0; i < files.length; i++) {
        loadIndex = layer.msg('加载中', { icon: 16, shade: [0.9, '#FFF'], time: 1000 * 30 });
        const file = files[i];
        var reader = new FileReader();
        reader.onload = openBook;
        reader.readAsArrayBuffer(file);
      }
      updateType = '本地';
    })

    var loadIndex = 0;
    layui.use(['jquery', 'form', 'layer', 'tree'], function () {
      var $ = layui.jquery
      var form = layuiForm = layui.form
      var tree = layuiTree = layui.tree
      var util = layui.util;

      util.on('lay-on', {
        // 通过 url 获取epub图书，并获取基础信息
        'getUrlBook': function () {
          let url_ = document.getElementById('updateUrl_input').value;
          if (!url_.trim()) { alert('不能为空'); return };
          loadIndex = layer.msg('加载中', { icon: 16, shade: [0.9, '#FFF'], time: 1000 * 30 });
          fetch(url_, {}).then(response => {
            if (response.status >= 200 && response.status < 300) { // 判断请求是否成功
              return response.blob() // 得到二进制 Blob 对象。
            } else {
              throw new Error(response.statusText);
            }
          }).then(json => {
            var reader = new FileReader();
            reader.onload = openBook;
            reader.readAsArrayBuffer(json);
            updateType = '远程';
          }).catch(err => {
            console.log('通过url获取图书失败', err)
            alert(`通过url获取图书失败,错误为：\n\n ${err.message}\n\n打开控制台查看详细信息`)
            layer.close(loadIndex);
          });
        }
      })
    })

    // 通过本地上传文件获取epub图书，并获取基础信息
    function openBook(e) {
      let bookData = e.target.result;
      let id = epubFunc.createDiv()
      let book = epubFunc.InitBook(bookData, id);
      epubFunc.getInfo(book).then(res => {
        epubFunc.blobToBase64(res.blob, (base64) => {
          layer.close(loadIndex);
          setToIdb({
            title: res.title + '-id-' + res.identifier,
            creator: res.creator,
            percentage: '0%', //  百分比
            cover: base64, // 图片
            bookData: bookData, // 图书文件
            type: updateType || '本地',
            creatDate: new Date().getTime(),
            readDate: new Date().getTime(),
          })
        })
      }, error => {
        console.log(`errlr`, error)
      })
    }

    // 保存图书数据到idb。obj=> title,creator,percentage,cover,bookData
    function setToIdb(obj) {
      function t(obj) {
        bookData = obj.bookData;
        cover = obj.cover;
        obj.id = parseInt(Math.random() * 1000000000000);
        obj.bookData = 'book_' + obj.title;
        obj.cover = 'img_' + obj.title;
        Promise.all([
          set(obj.title, obj),
          set_booksData_imgsData(obj.bookData, bookData),
          set_booksData_imgsData(obj.cover, cover)
        ]).then((results) => {
          setBooksToDiv()
        }).catch((error) => {
          alert('保存图书失败!'), console.log('保存图书失败!', err)
        });
      }
      keys().then((keys) => {
        if (keys.includes(obj.title)) {
          let confirmed = confirm(`《${obj.title}》已经存在了，确认重新上传吗？`);
          if (confirmed) {
            t(obj);
          } else {
            console.log("用户选择取消。");
          }
        } else {
          t(obj);
        }
      });
    }

    // 刷新展示图片项
    function setBooksToDiv() {
      let books = document.getElementById('books');
      books.innerHTML = '';
      values().then((values) => {
        // console.log(values)
        values.sort(function (obj1, obj2) {
          return obj2.readDate - obj1.readDate;
        });
        values.forEach(element => {
          var newDiv = document.createElement("div");
          newDiv.classList.add('layui-col-xs6');
          newDiv.classList.add('layui-col-ms12');
          newDiv.classList.add('layui-col-md3');
          newDiv.innerHTML = `
            <div class="delete" onclick="deleteBook('${element.title}')">
              <i class="layui-icon layui-icon-clear" style="font-size: 30px; color: #ff8080;"></i>
            </div>
            <a href="readBook.html${setUrlforObject({
            bookName: element.title,
          })}" target="" rel="noopener noreferrer">
              <div class="bookImg">
                <img src="./images/暂无图片.gif" id="${element.id}" srcset="">
              </div>
              <div class="bookTitle">${element.title}</div>
              <div class="read">
                <div class="bookType">${element.type}-</div>
                <div class="bookCreator">${element.creator}</div>
                <div class="bookRead">${element.percentage}</div>
              </div>
            </a>
          `
          books.appendChild(newDiv);
          get_booksData_imgsData(element.cover).then(res => { if (res.length < 100) return; document.getElementById(element.id).src = res; })
        });
      });
    }

    function deleteBook(bookName_) {
      // console.log(`bookName_`, bookName_);
      let confirmed = confirm(`确定要删除？\n\n ${bookName_}`);
      if (confirmed) {
        del(bookName_);
        del_booksData_imgsData('book_' + bookName_);
        del_booksData_imgsData('img_' + bookName_);
        setBooksToDiv();
      } else {
        console.log("用户选择取消。");
      }
    }

    window.onload = function () { setBooksToDiv(); };

  </script>


</body>

</html>